%% 使用 single 数据进行 RPC 模型拟合
% 
% 结论:
%   1. 在double精度下, SVD和LC精度均可达1e-5, SVD的精度更加高些
%   2. 在single精度下, SVD精度大于1个像素(存在失败), LC精度在0.1至0.2像素
%       SVD 建议将值归一化到 -0.1 至 0.1，否则容易求解失败
close all;
clear;

%%
id = 4;
is_single = true;

%%
test_fitrpc(is_single, id);

%%

function test_fitrpc(is_single, id)

if is_single
    mark_single = 's';
else
    mark_single = 'd';
end

dat_path = sprintf('datas/%02d/resamp_%02d.dat', id, id);
rpc_svd_path = sprintf('datas/%02d/svd_%02d_%c.rpc', id, id, mark_single);
rpc_lc_path = sprintf('datas/%02d/lc_%02d_%c.rpc', id, id, mark_single);

%% 1. 加载拟合数据
[vgcp_x, vgcp_y, vgcp_z, vgcp_col, vgcp_row, img_size] = loadResampDat(dat_path);

if is_single
    vgcp_x = single(vgcp_x);
    vgcp_y = single(vgcp_y);
    vgcp_z = single(vgcp_z);
    vgcp_col = single(vgcp_col);
    vgcp_row = single(vgcp_row);
end

%% 2. 使用 SVD+ICCV
rpc_model_svd = hsRPC.fitting(vgcp_x, vgcp_y, vgcp_z, vgcp_col, vgcp_row ...
    , 'backward', "ImgSize", img_size, "Method", 'SVD+ICCV', "K", 0.1);
hsRPC.write(rpc_model_svd, rpc_svd_path);

[est_col, est_row] = hsRPC.project(rpc_model_svd, vgcp_x, vgcp_y, vgcp_z);
error_col_svd = est_col - vgcp_col;
error_row_svd = est_row - vgcp_row;

figure;
subplot(211);
plot(error_col_svd);
title("SVD error x");
grid on;
subplot(212);
plot(error_row_svd);
title("SVD error y");
grid on;

%% 3. 使用 LC+ICCV
rpc_model_lc = hsRPC.fitting(vgcp_x, vgcp_y, vgcp_z, vgcp_col, vgcp_row ...
    , 'backward', "ImgSize", img_size, "Method", 'LC+ICCV');
hsRPC.write(rpc_model_lc, rpc_lc_path);

[est_col, est_row] = hsRPC.project(rpc_model_lc, vgcp_x, vgcp_y, vgcp_z);
error_col_lc = est_col - vgcp_col;
error_row_lc = est_row - vgcp_row;

figure;
subplot(211);
plot(error_col_lc);
title("LC error x");
grid on;
subplot(212);
plot(error_row_lc);
title("LC error y");
grid on;

end
